package ma.jeetconsulting.pocs.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.UnsupportedCharsetException;
import java.util.List;
import java.util.regex.Pattern;

public class JavaFile {

	private static final String PACKAGE = "package ";

	private static final int READ_BUFFER_SIZE = 1024;

	private static final Pattern GENERIC_LINE_TERMINATOR = Utils
			.getPattern("\\n|\\r\\n?");

	private final File file;

	private final Charset charset;

	private final CharSequence fullText;

	private final String[] linesWitoutTerminators;

	public JavaFile(File aFile, String aCharsetName) throws IOException {
		file = aFile;

		final CharsetDecoder decoder;
		try {
			charset = Charset.forName(aCharsetName);
			decoder = charset.newDecoder();
			decoder.onMalformedInput(CodingErrorAction.REPLACE);
			decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
		} catch (final UnsupportedCharsetException ex) {
			final String message = "Unsuppored charset: " + aCharsetName;
			final UnsupportedEncodingException ex2;
			ex2 = new UnsupportedEncodingException(message);
			ex2.initCause(ex);
			throw ex2;
		}

		final char[] chars = new char[READ_BUFFER_SIZE];
		final StringBuilder buf = new StringBuilder();
		final FileInputStream stream = new FileInputStream(aFile);
		final Reader reader = new InputStreamReader(stream, decoder);
		try {
			while (true) {
				final int len = reader.read(chars);
				if (len < 0) {
					break;
				}
				buf.append(chars, 0, len);
			}
		} finally {
			Utils.closeQuietly(reader);
		}
		fullText = buf.toString();

		final String[] lines = GENERIC_LINE_TERMINATOR.split(fullText, -1);
		if (lines.length > 0 && lines[lines.length - 1].length() == 0) {
			linesWitoutTerminators = new String[lines.length - 1];
			System.arraycopy(lines, 0, linesWitoutTerminators, 0,
					lines.length - 1);
		} else {
			linesWitoutTerminators = lines;
		}
	}

	public boolean containsAnyOfThesesPackages(List<String> packages) {
		for(String pack : packages)
			for(String line : linesWitoutTerminators)
				if(line.contains(pack))
					return true;
		return false;

	}
	
	@Override
	public String toString() {
		return file.getName();
	}
	
	public String getPackageName() {
		for(String line : linesWitoutTerminators)
			if(line.trim().startsWith(PACKAGE)) {
				return getNameOfPackage(line);				
			}
		return "";
	}

	private String getNameOfPackage(String line) {
		return line.trim().substring(7).trim();
	}
	
	
	public String getClassName() {
		return file.getName().replace(".java", "");
	}
	
	public String getClassNamePrefixedByPackage() {
		return getPackageName() + "." + getClassName();
	}
}